/*
* Copyright(C) 2009, kesalin All rights reserved.
* 
* File name : UHostUIHandler.h
* Brief     : HostUIHandler.
* Version   : 1.0
* Author    : kesalin@gmail.com
* Date      : 2009-6-5
*/

#pragma once

#include "UCommon.h"

namespace LuoUtils {

// UHostUIHandler
class UHostUIHandler :
	public IDocHostUIHandlerDispatch {

	ATL::CComPtr<IDropTarget> m_Target;
	ATL::CComPtr<IDispatch>   m_External;

	DWORD m_AmbientDLControl;

public:

	UHostUIHandler() : m_AmbientDLControl(0)
	{
	}

	~UHostUIHandler()
	{
	}

	/* */

	void SetupDropTarget(IDropTarget* p)
	{
		m_Target = p;
	}

	void SetupExternal(IDispatch* p)
	{
		m_External = p;
	}

	void SetupAmbientDLControl(DWORD dw)
	{
		m_AmbientDLControl = dw;
	}

	/* IUnknown */

	STDMETHOD(QueryInterface)(
		REFIID riid,
		void** ppvObject)
	{
		if (ppvObject == 0) {
			return E_POINTER;
		}

		*ppvObject = 0;

		if (riid == IID_IUnknown || riid == IID_IDispatch) {
			*ppvObject = static_cast<IDispatch*>(this);
			return S_OK;
		}

		return E_NOINTERFACE;
	}

	STDMETHOD_(ULONG, AddRef)(void)
	{
		return 1;
	}

	STDMETHOD_(ULONG, Release)(void)
	{
		return 1;
	}

	/* IDispatch */

	STDMETHOD(GetTypeInfoCount)(
		UINT* pctinfo)
	{
		return E_NOTIMPL;
	}

	STDMETHOD(GetTypeInfo)(
		UINT        itinfo,
		LCID        lcid,
		ITypeInfo** pptinfo)
	{
		return E_NOTIMPL;
	}

	STDMETHOD(GetIDsOfNames)(
		REFIID    riid,
		LPOLESTR* rgszNames,
		UINT      cNames,
		LCID      lcid,
		DISPID*   rgdispid)
	{
		return E_NOTIMPL;
	}

	STDMETHOD(Invoke)(
		DISPID      dispidMember,
		REFIID      riid,
		LCID        lcid,
		WORD        wFlags,
		DISPPARAMS* pdispparams,
		VARIANT*    pvarResult,
		EXCEPINFO*  pexcepinfo,
		UINT*       puArgErr)
	{
		switch (dispidMember) {
		case DISPID_AMBIENT_DLCONTROL:
			if (m_AmbientDLControl != 0) {
				pvarResult->vt   = VT_I4;
				pvarResult->lVal = m_AmbientDLControl;
				return S_OK;
			}
			break;
		}

		return E_NOTIMPL;
	}

	/* IDocHostUIHandlerDispatch */

	STDMETHOD(ShowContextMenu)(
		DWORD      dwID,
		DWORD      x,
		DWORD      y,
		IUnknown*  pcmdtReserved,
		IDispatch* pdispReserved,
		HRESULT*   dwRetVal)
	{
		*dwRetVal = S_OK;
		return S_OK;
	}

	STDMETHOD(GetHostInfo)(
		DWORD* pdwFlags,
		DWORD* pdwDoubleClick)
	{
		return E_NOTIMPL;
	}

	STDMETHOD(ShowUI)(
		DWORD     dwID,
		IUnknown* pActiveObject,
		IUnknown* pCommandTarget,
		IUnknown* pFrame,
		IUnknown* pDoc,
		HRESULT*  dwRetVal)
	{
		return E_NOTIMPL;
	}

	STDMETHOD(HideUI)(void)
	{
		return E_NOTIMPL;
	}

	STDMETHOD(UpdateUI)(void)
	{
		return E_NOTIMPL;
	}

	STDMETHOD(EnableModeless)(
		VARIANT_BOOL fEnable)
	{
		return E_NOTIMPL;
	}

	STDMETHOD(OnDocWindowActivate)(
		VARIANT_BOOL fActivate)
	{
		return E_NOTIMPL;
	}

	STDMETHOD(OnFrameWindowActivate)(
		VARIANT_BOOL fActivate)
	{
		return E_NOTIMPL;
	}

	STDMETHOD(ResizeBorder)(
		long         left,
		long         top,
		long         right,
		long         bottom,
		IUnknown*    pUIWindow,
		VARIANT_BOOL fFrameWindow)
	{
		return E_NOTIMPL;
	}

	STDMETHOD(TranslateAccelerator)(
		DWORD_PTR hWnd,
		DWORD     nMessage,
		DWORD_PTR wParam,
		DWORD_PTR lParam,
		BSTR      bstrGuidCmdGroup,
		DWORD     nCmdID,
		HRESULT*  dwRetVal)
	{
#if 0
		if (dwRetVal != 0) {
			*dwRetVal = S_FALSE;
		}
		return S_OK;
#else
		return E_NOTIMPL;
#endif
	}

	STDMETHOD(GetOptionKeyPath)(
		BSTR* pbstrKey,
		DWORD dw)
	{
		return E_NOTIMPL;
	}

	STDMETHOD(GetDropTarget)(
		IUnknown*  pDropTarget,
		IUnknown** ppDropTarget)
	{
		if (m_Target != 0) {
			if (ppDropTarget == 0) {
				return E_INVALIDARG;
			}

			*ppDropTarget = m_Target;

			(*ppDropTarget)->AddRef();

			return S_OK;
		}

		return E_NOTIMPL;
	}

	STDMETHOD(GetExternal)(
		IDispatch** ppDispatch)
	{
		if (ppDispatch == 0) {
			return E_INVALIDARG;
		}

		if (m_External == 0) {
			return E_NOTIMPL;
		}

		IDispatch* disp = m_External;

		*ppDispatch = disp;

		disp->AddRef();

		return S_OK;
	}

	STDMETHOD(TranslateUrl)(
		DWORD dwTranslate,
		BSTR  bstrURLIn,
		BSTR* pbstrURLOut)
	{
		return E_NOTIMPL;
	}

	STDMETHOD(FilterDataObject)(
		IUnknown*  pDO,
		IUnknown** ppDORet)
	{
		return E_NOTIMPL;
	}

}; // UHostUIHandler

} // namespace LuoUtils

